package controller

import (
	"imooc.com/crawler/frontend/view"
	"github.com/olivere/elastic"
	"net/http"
	"strings"
	"strconv"
	"imooc.com/crawler/frontend/model"
	"context"
	"reflect"
	"imooc.com/crawler/engine"
	"regexp"
)

type SearchResultHandler struct {
	view view.SearchResult
	client *elastic.Client
}

/**
  路由指定的方法
 */
// localhost:8888/search?q=(青岛)AND(乐乐)&from=20
// q=(青岛)AND(乐乐)/(青岛)OR(乐乐)/(青岛)AND(Payload.Age:(<=29))/(青岛)OR(乐乐)/(青岛)AND(Payload.Age:([1 TO 29]))
func (h SearchResultHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {

	q := strings.TrimSpace(req.FormValue("q"))
	from, err := strconv.Atoi(req.FormValue("from"))
	if err != nil {
		from = 0
	}

	page, err := h.getSearchResult(q, from)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

	err = h.view.Render(w, page)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

}
/**
获取搜索结果
 */
func (h SearchResultHandler) getSearchResult(q string, from int) (model.SearchResult, error)  {
	var result model.SearchResult

	service := h.client.Search("dating_profile")
	if q != "" {
		service.Query(elastic.NewQueryStringQuery(rewriteQueryString(q)))
		result.Q = q
	}
	if from > 0 {
		service.From(from)
	}

	resp, err := service.Size(1).Do(context.Background())
	if err != nil {
		return result, err
	}
	result.Hits = resp.TotalHits()
	result.Start = from
	result.Items = resp.Each(reflect.TypeOf(engine.Item{}))
	result.PreFrom = (from - len(result.Items))
	result.NextFrom = (from + len(result.Items))


	return result, nil

}
//初始化控制器
func CreateSearchResultHandler(template string) SearchResultHandler  {
	client, err := elastic.NewClient(
		elastic.SetSniff(false), //默认为true,开启集群模式
		elastic.SetURL("http://192.168.33.10:9200"),
	)
	if err != nil {
		panic(err)
	}

	return SearchResultHandler{
		view: view.CreateSearchResultView(template),
		client: client,
	}
}

func rewriteQueryString(q string) string  {
	re := regexp.MustCompile(`([A-Z][a-z]*):`)
	return re.ReplaceAllString(q, "Payload.$1:")
}

